from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy, BaseQuery
from sqlalchemy import Column, Integer, String, Boolean, Float, ForeignKey, SmallInteger, DateTime
from contextlib import contextmanager
from datetime import datetime


class SQLAlchemy(_SQLAlchemy):
    @contextmanager
    def auto_commit(self):
        try:
            yield  # 到这里后执行 with下的sql操作代码，然后走下一步
            self.session.commit()
        except Exception as e:
            db.session.rollback()  # 错误回滚
            raise e


class Query(BaseQuery):
    #改写 filter_by
    def filter_by(self, **kwargs):
        if 'del_status' not in kwargs.keys():
            kwargs['del_status'] = 1
        return super(Query, self).filter_by(**kwargs)
    # def filter(self,**kwargs):
    #     return super(Query, self).filter(**kwargs)



db = SQLAlchemy(query_class=Query)


class Base(db.Model):
    __abstract__ = True  # 在启动flask时会自动创建 继承了 db.Model 的模型，这个设置是让flask不创建
    create_time = Column('create_time', DateTime,default=datetime.now)
    del_status = Column(SmallInteger, default=1)


    def set_attrs(self, attrs_dict):
        # 遍历attrs_dict，如果有key和模型的属性（数据库字段）相同，就把这个key的值赋值给模型
        for key, value in attrs_dict.items():
            if hasattr(self, key) and key != 'id':  # 函数判断一个对象是否有某个属性， self 表示当前模型对象
                setattr(self, key, value)  # 对self对象的属性名为key的赋值，值为value。动态赋值
    def __getitem__(self,item):#内置函数根据传入的键值,返回每个键的值，配合keys()方法使用
        return getattr(self,item)
    # '''用于序列化模型类'''
    # def keys(self):#用于拿到字典所有的键，自己指定，也可以拿部分
    #     return self.fields
    #
    # # 内置函数根据传入的键值,返回每个键的值，配合keys()方法使用
    # def __getitem__(self,item):#内置函数根据传入的键值,返回每个键的值，配合keys()方法使用
    #     return getattr(self,item)
    def keys(self):
        return self.fields

    def hide(self,*keys):
        for key in keys:
            self.fields.remove(key)
        return self
    def append(self,*keys):
        for key in keys:
            self.fields.append(key)
        return self

